/*选人组件*/
import { Modal, Select, Form, Input, Table, Tag, Button, DatePicker, Row, Col } from "antd";
import { forwardRef, useState ,useRef, useEffect, useLayoutEffect} from "react";
import message from "../../utils/message";
import request from "../../utils/request";
import qs from "qs";
import clsx from "clsx";
import { useDeepCompareEffect, useUpdate} from "ahooks";
import moment from "moment";
import cloneDeep from 'lodash/cloneDeep'
import uniqBy from "lodash/uniqBy"
import uniq from "lodash/uniq"
import useTable from "../../lifecycle/useTable";
import { formatNumber, getDatePicker, isNoEmptyArray, parseDateformat } from "../../utils";
import "./dataConnect.css"
import {replaceHref} from "./utility"//数据互联组件的公共方法
import { DownOutlined, UpOutlined } from '@ant-design/icons';
import chunk from "lodash/chunk"
import jQuery from "jquery";
window.jQuery = jQuery;

export default function({
  fieldName="数据互联",//字段中文name
  className,//额外的class 比如校验失败
  placeholder="请选择",//表单设计器提示语
  value=[],//默认值
  column,//业务对象配置的列信息
  data_template={},//业务对象配置的数据格式
  queryCode="",//业务对象配置的搜索字段code
  advancedQuery=[],//高级搜索
  sortCode="",//业务对象配置的排序字段code
  textField="",//业务对象配置的要显示为文本的字段
  package_id="",//package_id
  process_id="",//流程id?
  fullCode="",//主表取值：字段code 子表取值：分组code.字段code
  groupCode,//字段所在分组code，注：子表取的是分组code  主表取的是主表code（不是主表分组code）
  isSubTableField,//是否子表
  rowIndex,//如果子表，标记当前字段的行索引
  multiple=0,//单选|多选
  tplData,
  pageSize=10,//分页
  onChange,//字段数据变化事件
  href=""//数据互联配置的超链接
}) {

  const [modalShow, setModalShow] = useState(false);//弹出框显示状态
  const selectRef = useRef(null);//select dom对象
  const tableRef = useRef({});//table的dom对象
  /*
    uniqCode = 每行数据的唯一标记code
    data_template?.uniqCode = cell.props.data_template.uniqCode，优先取这个
    textField = cell.props.data_template.display 如果不存在，再取这个
  */
  let uniqCode =  data_template?.uniqCode || textField;

  const [selectValue, setSelectValue] = useState([]);//ant select组件需要的值
  
  //设置select的value
  function setValue(value){
    let returnData = [];
    value.forEach(function(item){
        returnData.push(
          {
            value: item,
            label: item[textField],
            key: item[uniqCode]
          }
        );//select组件可接受这个格式的值，label为显示的恩本，value为实际的值，可接受对象，key为唯一标识即可
    });
    setSelectValue(returnData);//更新select的显示值
  }//设置实际值
  
  useDeepCompareEffect(function(){
    setValue(value || []);//初始化设置默认值
  },[value]);

  return <>
    <Modal
      bodyStyle={{padding:0}}
      destroyOnClose={true}
      centered={true}
      title={fieldName}
      width={960}
      visible={modalShow}
      onOk={()=>{
        let selectRows = tableRef.current.getSelectRows();//获取选中行
        onChange(selectRows);
        setModalShow(false);//隐藏弹出框
      }}
      onCancel={()=>{
        setModalShow(false);//隐藏弹出框
      }}
    >
      <div className="ml-7 mr-7 max-h-[560px] overflow-auto pr-[1px]">
        <DataConnectTable
          tableRef={tableRef}
          column={column}
          data_template={data_template}
          queryCode={queryCode}
          textField={textField}
          uniqCode={uniqCode}
          sortCode={sortCode}
          package_id={package_id}
          process_id={process_id}
          fullCode={fullCode}
          groupCode={groupCode}
          isSubTableField={isSubTableField}
          rowIndex={rowIndex}
          multiple={multiple}
          tplData={tplData}
          defaultValue={value}
          pageSize={pageSize}
          advancedQuery={advancedQuery}
          ></DataConnectTable>
      </div>
    </Modal>
    <Select
      ref={selectRef}
      className={clsx("person-select", className)}
      value={selectValue}
      labelInValue
      optionLabelProp="station_name"
      dropdownRender={()=>{
        return <></>
      }}
      tagRender={(props)=>{
        props.href = replaceHref({
          url: href,
          itemData: props.value,
          host: tplData.ServerAddr,
          column: column
        });//组件配置的href信息
        return TagRender(props);
      }}
      dropdownClassName={"person-select-dropdown"}
      mode="tags"
      style={{ width: '100%' }}
      placeholder={placeholder}
      suffixIcon={<span className="add_icon"></span>}
      onClick={(e)=>{
        selectRef.current.blur();//selct失去焦点
        if(e.target?.dataset?.tag === "link"){//如果是点击的hrel，不做弹出操作
          
        }else{
          setModalShow(true);//显示弹出框
        }
      }}
      onChange={(val, options) => {
        var fieldData = [];
        val.map(function(item){
          fieldData.push(item.value);
        });
        setValue(fieldData);//设置select组件的值
        onChange(fieldData);//更新外部表单字段的值
      }}
      showArrow = {true}
    ></Select>
  </>
}

//数据互联table
function DataConnectTable(props){
  let {
    column,
    data_template,
    queryCode,
    uniqCode,
    textField,
    sortCode,
    package_id,
    process_id,
    fullCode,
    groupCode,
    isSubTableField,
    rowIndex,
    tplData,
    multiple,
    tableRef,
    pageSize,
    defaultValue,
    advancedQuery
  } = props;

  const update = useUpdate();
  let tableConfig = useRef({
    advancedQueryVisible: false,//高级搜索模式展开状态
    update: update//更新组件
  });//table组件依赖属性

  let selectedRows = useRef(defaultValue);//已选中的行数据，需要给到组件本身
  let selectCompontData = useRef(
                                  getSelectCompontData({
                                    rows: defaultValue,
                                    textField: textField,
                                    uniqCode: uniqCode
                                  })
                                );//ant select组件需要的数据
                          
  useLayoutEffect(()=>{
    //开启了高级查询才走这个逻辑
    if(isNoEmptyArray(advancedQuery)){
      let searchFormHeight = jQuery(".js-dataConnectForm").outerHeight(true);//搜索区高度
      let tableHeight = 500 - searchFormHeight - 43;//table内容区高度 = 弹出框高度 - 搜索区高度 - table表头高度
      let minHeight = 416;//正常表格最小高度
      if(tableHeight <= minHeight/2){//如果展开后挤压高度小于最小高度一半，则不再挤压
        tableHeight = minHeight/2;
      }
      jQuery(".js-table-dataConnect .ant-table-body").css({
        "maxHeight": tableHeight,
        "minHeight": tableHeight
      });//给table增加高度限制
      update();
    }
  }, [tableConfig.current.advancedQueryVisible])

  let defaultKeys = defaultValue.map(function(item){ return item[uniqCode]});//默认keys
  let tableSelectedKeys = useRef(defaultKeys);//缓存已选中的行id，用来做列表的选中回填

  const selectRef = useRef(null);//select dom对象

  tableRef.current.getSelectRows = function (){
    return selectedRows.current;
  };//返回已选中的行给父组件

  //数据互联的搜索字段信息
  let searchInfo = {
    type:"",
    format:""
  };
  column = column.filter(function(col){
    return col.isShow == 1
  });//table只展示isShow=1的列
  column.forEach(function(col){
      if(col.code == queryCode){
          searchInfo.type = col.type;
          searchInfo.format = col.format;
      }
  });

  //获取查询需要的字段数据
  let query_source = {};
  if(isSubTableField){//子表
    query_source[groupCode] = tplData.form.form_data.children[groupCode][rowIndex];//取字段所在行的子表数据
  }else{//主表
    query_source[tplData.form.data_define.main.code] = tplData.form.form_data.main;//取主表数据
  }
  
  //生成table组件
  const [form] = Form.useForm();
  const { tableProps, search } = useTable(
    (
      {
        current = 1, // 设定初始在第1页
        pageSize, // 初始每页默认10条数据
        // sorter,
      },
      formData
    ) => {

      let postData = {
        page_index: current,
        page_size: pageSize,
        search_words: formData.keyword || "",
        package_id: package_id,
        process_id: process_id,
        query_field: fullCode,
        query_source: query_source,
        search_field: queryCode,
        search_format: searchInfo.format,
        search_type: searchInfo.type,
        sort: sortCode,
        advancedQuery:  __getAdvancedQueryData({
          formData: formData,
          data_template: data_template
        })//高级搜索表单信息
      }

      return request({
        url: "/flowinstance/approval/get-data-connect-query",
        method: "post",
        data: postData
      }).then(function (response) {
        let list = response?.data?.list || [];
        list.forEach((item, index) => {
          item.index = index + 1 + (current - 1) * 10;//设置序号
        });
        return {
          total: response.data.total,
          list: list,
        };
      });
    },
    {
      form,
      defaultPageSize: pageSize
    }
  );
  const { submit } = search;

  let resetForm = function(){
    form.resetFields();
  }

  //生成table列信息
  let columns = [
    {
      title: "序号",
      dataIndex: "index",
      width: 50,
    }
  ];
  column = column.map(function(col){
    return  {
      ...{
        title: col.name,
        dataIndex: col.code,
        // width: 100,
        ellipsis: true,
        render:function(text, record, index){
          let renderText = text;
          if(col.format){//存在格式化属性
            if(text){
              switch(col.type){
                case "date":
                  let format = col.format.replace("yyyy-MM-dd", "YYYY-MM-DD").replace("hh", "HH"); //转为moment需要的时间格式
                  renderText = moment(text).format(format);//格式化时间
                  break;
                case "num":
                  renderText = formatNumber(text,{
                    precision: 2,
                    is_thousandth: true
                  });//格式化数值
                  break;
                default:
                    break;
              }
            }
          }
          return renderText
        }
      }//这些是ant的配置，参见ant table组件配置说明
    }
  });//清洗配置的列数据为ant需要的参数
  columns = columns.concat(column);//给配置的列合并一个默认序号列

  //设置输入框placeholder
  let searchPlaceholder = "请输入";
  // 下面这段代码是生成普通搜索 Placeholder ，po临时调整为请输入，防止需求变更，先注释掉
  // if(queryCode !== ""){
  //   columns.find(function(col){
  //     if(col.dataIndex === queryCode){
  //       searchPlaceholder = "请输入" + col.title;
  //       return true;
  //     }
  //   });
  // }
  return <>
    {
      multiple != 0
      && <div className="mb-3">
          <Select
            ref={selectRef}
            className={clsx("")}
            value={selectCompontData.current}
            // labelInValue
            optionLabelProp="station_name"
            dropdownRender={()=>{
              return <></>
            }}
            dropdownClassName={"person-select-dropdown"}
            mode="tags"
            style={{ width: '100%' }}
            onClick={(e)=>{
              selectRef.current.blur();//selct失去焦点
            }}
            onChange={(val, options) => {
              let keys = val.map(function(item){
                return item[uniqCode];
              })
              tableSelectedKeys.current = keys;//更新选中key
              selectedRows.current = val;//更新选中行
              selectCompontData.current = getSelectCompontData({
                rows: val,
                textField: textField,
                uniqCode: uniqCode
              });//更新ant select组件的展示效果
              update();
            }}
            showArrow = {false}
          ></Select>
        </div>
    }

    <div
      className={clsx(
        "mb-3 overflow-hidden dataConnectForm js-dataConnectForm",
        isNoEmptyArray(advancedQuery) && "border border-solid border-d9d9d9 py-3"//开启了高级筛选时，才包含这些样式
      )}
    >
      <Form
        form={form}
        labelAlign="left"
        labelCol={{
          flex: "80px",
        }}
        autoComplete="off"
      >
        <Row className={clsx(
          isNoEmptyArray(advancedQuery) && "px-4"//开启了高级筛选时，才包含这些样式
        )}>

          {/*普通查询 */}
          <Col span={16}>
            <Form.Item 
              name="keyword"
              label={data_template.queryName || ""}
            >
              {
                tableConfig.current.advancedQueryVisible === true//展开高级搜索时，普通搜索不显示搜索按钮
                ? <Input placeholder={searchPlaceholder} style={{ width: 290}} />
                : <Input.Search placeholder={searchPlaceholder} onSearch={submit} style={{ width: 290}} />
              }
            </Form.Item>
          </Col>

          <Col span={8} className="text-right">
            {
              /*配置了高级搜索时显示展开收起 */
              (isNoEmptyArray(advancedQuery))
              && <span
                  className="text-default-color cursor-pointer leading-8"
                  onClick={()=>{
                    //切换展开收起状态
                    tableConfig.current.advancedQueryVisible = !tableConfig.current.advancedQueryVisible;
                    tableConfig.current.update();
                  }}
                >
                  {
                    tableConfig.current.advancedQueryVisible
                    ? <>收起 <span className="text-color-666"><UpOutlined /></span></>
                    : <>展开 <span className="text-color-666"><DownOutlined /></span></>
                  }
                </span>
            }
          </Col>
        </Row>

        {
          (isNoEmptyArray(advancedQuery))
          && <>
              <AdvancedQuery advancedQuery={advancedQuery} tableConfig={tableConfig} onSearch={submit} resetForm={resetForm}></AdvancedQuery>
            </>
        }
      </Form>
    </div>

    <Table
      onRow={
        (record) => {
          return {
            onClick: event => {
              //做整行点击选中
              // if(selectedRowKeys.indexOf(event.currentTarget.dataset.rowKey) < 0){//当前点击的行处于未选中状态
              //   let newKeys = selectedRowKeys.push(event.currentTarget.dataset.rowKey)
              //   setSelectedRowKeys(newKeys);
              // }

            }, // 点击行
          };
        }
      }

      rowSelection={{
        type: multiple == 0 ? "radio" : "checkbox",
        preserveSelectedRowKeys: true,
        selectedRowKeys: tableSelectedKeys.current,
        columnWidth: 43,
        onSelect: (record, selected, selectedR, nativeEvent)=>{//行选中事件
          if(multiple == 0){//单选
            tableSelectedKeys.current = [record[uniqCode]];//更新选中key
            delete record.index;
            selectedRows.current = [record].slice();//更新选中行
          }else{//多选
            if(selected === true){//选中
              tableSelectedKeys.current = tableSelectedKeys.current.concat([record[uniqCode]]);//更新选中key
              selectedRows.current = selectedRows.current.concat([record]);//更新选中行
            }else{//取消选中
              tableSelectedKeys.current = tableSelectedKeys.current.filter(function(item){
                return item !== record[uniqCode];//去掉本次取消的key 
              });//更新选中keys
              selectedRows.current = selectedRows.current.filter(function(item){
                if(tableSelectedKeys.current.indexOf(item[uniqCode]) > -1){
                  delete item.index;
                  return item;//根据选中key更新已选行数据
                }
              });//更新已选行数据
            }
          }

          selectCompontData.current = getSelectCompontData({
            rows: selectedRows.current,
            textField: textField,
            uniqCode: uniqCode
          });//更新ant select组件的展示效果

          update();
        },
        onSelectAll: (selected, selectedRs, changeRows) => {//全选反选事件
          if(selected === true){//全选
            
            tableSelectedKeys.current = tableSelectedKeys.current.concat(changeRows.map(function(item){
              return item[uniqCode];
            }));//更新选中key

            selectedRows.current = selectedRows.current.concat(changeRows);//更新选中行
            selectedRows.current = selectedRows.current.map(function(item){
              delete item.index;
              return item;
            })
          }else{//全不选

            let deleteKeys = [];
            changeRows.forEach(function(item){
              deleteKeys.push(item[uniqCode]);
            });//拿到所有删除的keys

            tableSelectedKeys.current = tableSelectedKeys.current.filter(function(item){
              if(deleteKeys.indexOf(item) < 0 ){//去掉删除的key
                return item;
              }
            })//更新选中行

            selectedRows.current = selectedRows.current.filter(function(item){
              if(tableSelectedKeys.current.indexOf(item[uniqCode]) > -1){
                delete item.index;
                return item;
              }
            });//根据选中key更新已选行数据
          }

          selectCompontData.current = getSelectCompontData({
            rows: selectedRows.current,
            textField: textField,
            uniqCode: uniqCode
          });//更新ant select组件的展示效果

          update();
        }
      }}
      className="table-madol js-table-dataConnect"
      columns={columns}
      scroll={{ y: 360 }} 
      rowKey={uniqCode}
      {...tableProps}
    />
  </>
}

//自定义select的tage
function TagRender (props) {
  const { label, value, closable, onClose } = props;
  return (
    <Tag
      closable={closable}
      className="mysoft-tag-connect text-sm"
      onClose={onClose}
    >
      {
        props.href
        ? <a href={props.href} data-tag="link" key={label} target="_blank" className="inline-block  text-sm hover:underline">{label}</a>
        : label
      }
    </Tag>
  );
};

//高级搜索
function AdvancedQuery({
  advancedQuery,//业务对象内高级搜索的配置
  tableConfig,//组件的依赖配置
  onSearch,//触发table的搜索
  resetForm//重置表单并搜索
}){
  let chunkAdvancedQuery = chunk(advancedQuery, 2);//高级搜索每行展示两个字段，切割成2个一组的数组
  return <>
    {
      tableConfig.current.advancedQueryVisible
      && <>
          {
            chunkAdvancedQuery.map(function(queryRows, index){
              return <div
                        className="overflow-hidden mt-3 px-4" 
                        key={index}
                      >
                        {
                          queryRows.map(function(queryField){
                            return <Form.Item
                                    className="w-[370px] float-left mr-3 advanced-item"
                                    key={queryField.code}
                                    label={queryField.name}
                                    name={queryField.code}
                                  >
                                    <FormItem queryField={queryField}></FormItem>
                                  </Form.Item>
                          })
                        }
                      </div>
            })
          }
        </>
    }

    <div className="mt-3 pt-3 px-4 border-t-d9d9d9 border-t border-solid">
      <Button type="primary" 
        size="small"
        onClick={()=>{
          onSearch();
        }}
      >搜索</Button>
      <Button 
        type="link"
        size="small"
        onClick={()=>{
          resetForm();
          onSearch();
        }}
      >清空</Button>
    </div>
  </>
}

//高级搜索字段组件，根据类型返回对应数据
function FormItem({
  queryField,
  onChange,
  value
}){
  let returnField = null
  switch(queryField.type){
    case "text":
      returnField = <Input onChange={onChange} value={value} placeholder="请输入"></Input>
      break;
    case "date":
      
      let format = parseDateformat({format: queryField.format});//转换为React需要的格式
      let [showTime, picker] = getDatePicker({format: format});

      returnField = <DatePicker 
                      allowClear={false}
                      showNow={true}
                      picker={picker}
                      showTime={showTime}
                      onChange={onChange} 
                      value={value} 
                      placeholder="请选择" 
                      className="w-full" 
                      onOk={()=>{}}
                      format={format} 
                    />
      break;
  }
  return returnField;
}

//把数组转换为ant select需要的结构
function getSelectCompontData({
  rows,
  textField,
  uniqCode
}){
  return rows.map(function(item){
    return {
      value: item,
      label: item[textField],
      key: item[uniqCode]
    }
  })
}

/**
 * 拼接高级查询表单字段给后端
 * @param {object} formData - 查询表单数据
 * @param {object} data_template - 字段在业务对象定义的props数据
 * @returns {object} 拼接好的高级查询表单信息
*/
function __getAdvancedQueryData({
  formData,
  data_template
}){
  let returnData = [];

  //遍历高级搜索配置，拼接高级搜索字段给后端
  isNoEmptyArray(data_template.advancedQuery) && data_template.advancedQuery.forEach((queryField)=>{
    let fieldValue = formData[queryField.code];
    if(fieldValue){//如果表单数据内存在字段值
      if(queryField.type === "date"){//搜索字段是日期类型
        let format = parseDateformat({format: queryField.format});
        fieldValue = fieldValue.format(format);//根据配置的format转为日期字符串
      }
      returnData.push({
        search_field: queryField.code,
        search_format: queryField.format || "",
        search_type: queryField.type,
        search_words: fieldValue
      })
    }
  })
  return returnData;
}